package ntu.sce.fyp.easilocation.datastore;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import ntu.sce.fyp.easilocation.datastore.model.Location;
import ntu.sce.fyp.easilocation.datastore.model.User;

public enum DatastoreHelper {
	INSTANCE;
	
	/** Handles creating a new user */
	public boolean createUser(String username, String password, String email, String phone, String birthday) {
		boolean flag = false;
		synchronized (this) {
			PersistenceManager pm = PMF.get().getPersistenceManager();
			User newUser = new User(username, password, email, phone, new Date(), null);
			try {
				pm.makePersistent(newUser);
				flag = true;
			} finally {
				pm.close();
			}	
		}
		return flag;
	}
	
	/** Handles checking operation for existing user */
	@SuppressWarnings("unchecked")
	public boolean checkUser(String username, String password) {
		PersistenceManager pm = PMF.get().getPersistenceManager();

		Query query = pm.newQuery(User.class);
	    query.setFilter("username == usernameParam");
	    query.declareParameters("String usernameParam");

	    boolean flag = false;
	    Object temp = null;
		try {
			temp = query.execute(username);
			if (temp != null) {
				List<User> users = (List<User>) temp;
				if (users.get(0).getPassword().equalsIgnoreCase(password)) {
					flag = true;
				}
			}
		} finally {
	        query.closeAll();
	        pm.close();
	    }
	    // the {@link User} object to return
	    return flag;
	}
	
	/** Handles retrieving location lists of an user */
	public List<Location> getAllLocations (String username){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<Location> locations;
		try {
			locations = pm.getObjectById(User.class, username).getLocations();
		} finally {
			pm.close();
		}
		return locations;
	}
	
	/** Handles retrieving most recent location of an user */
	@SuppressWarnings("unchecked")
	public Location getMostRecentLocation (String username) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery(Location.class);
		query.setFilter("username == usernameParam");
		query.declareParameters("String usernameParam");
		query.setOrdering("timestamp desc");
		
		Location mostRecentLocation = null;
		try {
			List<Location> locations = (List<Location>) query.execute(username);
			if (locations.size() != 0) {
				mostRecentLocation = locations.get(0);
			}
		} finally {
			query.closeAll();
			pm.close();
		}
		return mostRecentLocation;
	}
	
	/** Handles updating current location of an user */
	public void updateLocation (String username, Location location) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			User existingUser = pm.getObjectById(User.class, username);
			List<Location> oldLocations = existingUser.getLocations();
			if (oldLocations == null) {
				List<Location> newLocations = new ArrayList<Location>();
				newLocations.add(location);
				existingUser.setLocations(newLocations);
			} else {
				oldLocations.add(location);
			}
		} finally {
			pm.close();
		}
	}
	
	/** Handles deleting an user */
	public void removeUser (String username) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			User e = pm.getObjectById(User.class, username);
			pm.deletePersistent(e);
		} finally {
			pm.close();
		}
	}
}
